﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;
using BrokerBase.Lib.DataBase;
using NHibernate;
using Broker.Model;
using WCFDynamicProxyLibrary.DynamicProxy;
using System.Net.NetworkInformation;
using Broker.Update;
using System.Data;
using System.ServiceModel;
using Broker.DataService;
using Telerik.Windows.Controls;

namespace Broker
{
    /// <summary>
    /// UpdatePage.xaml 的交互逻辑
    /// </summary>
    public partial class UpdatePage : Page
    {
        private const int MAX_LENGTH=256*1024*1024;//256M的最大数据
        private BackgroundWorker downloadWorker=new BackgroundWorker();
        private IList<DBTable> tables = new List<DBTable>();

        private bool isFreeEdition = ! LicenseInfo.GetInstance().IsEffective;

        private RadWindow owner;


        public UpdatePage()
            : base()
        {
            InitializeComponent();
            

            Loaded += new RoutedEventHandler(PageDataUpdate_Loaded);
            downloadWorker.DoWork += downloadWorker_DoWork;
            downloadWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(downloadWorker_RunWorkerCompleted);
            
        }

        public UpdatePage(RadWindow owner)
            : this()
        {
            this.owner = owner;
            owner.PreviewClosed += new EventHandler<WindowPreviewClosedEventArgs>(owner_PreviewClosed);
        }

        void owner_PreviewClosed(object sender, WindowPreviewClosedEventArgs e)
        {
            if (downloadWorker.IsBusy)
            {
                MessageBox.Show("正在下载数据....请稍后再关闭窗口", "提示");
                e.Cancel = true;
            }
        }


        void DataWCF_ClientRegInfoChanged(BrokerBase.Lib.Client.ClientDataInfo info)
        {
            this.Dispatcher.Invoke(new Action(() =>
                {
                    SetUpdateState();
                }));
        }

        void PageDataUpdate_Loaded(object sender, RoutedEventArgs e)
        {
            AppGlobal.DataWCF.ClientRegInfoChanged += new ClientRegInfoChangedHandler(DataWCF_ClientRegInfoChanged);

            if (downloadWorker.IsBusy)
                return;

            ISession sess = AppGlobal.HbmSessionFactory.GetCurrentSession();

            SetUpdateState();

        }

        private void SetUpdateState()
        {
            if (AppGlobal.ResultClientRegInfo.IsNewData)
            {
                txtInfos.Text = "有新的数据可以更新";
                btnUpdate.IsEnabled = true;
            }
            else
            {
                txtInfos.Text = "没有可以更新的数据";
                btnUpdate.IsEnabled = false;
            }
        }

        private void btnUpdate_Click(object sender, RoutedEventArgs e)
        {
            if (isFreeEdition)
            {
                MessageBox.Show("免费版不能更新数据!,你可以可以重新下载一个包含最新产品数据的免费版.", "提示");
                return;
            }

            if (downloadWorker == null)
                downloadWorker = new BackgroundWorker();

            if (!downloadWorker.IsBusy)
            {
                btnUpdate.IsEnabled = false;
                txtInfos.Text = string.Empty;
                downloadWorker.RunWorkerAsync();
            }
        }



        private void downloadWorker_DoWork(object sender, DoWorkEventArgs e)
        {

            WriteText("正在连接服务器...", false);
            WriteText("这可能需要1分钟或更长时间,请等待......", true);

            ChannelFactory<IDataService> factory = AppGlobal.CreateDataServiceFactory();

            try
            {

                factory.Open();

                IDataService dataSvr = factory.CreateChannel();


                long ts = GetMaxCheckPoint();//获取本地最大时间戳

                string text = null; 

                text = dataSvr.CheckLastTimeStamp(ts);
                bool isRequired = Newtonsoft.Json.JsonConvert.DeserializeObject<bool>(text);
                WriteText("服务器连接成功", true);

                if (isRequired)
                {
                    WriteText("需要更新数据", false);
                    WriteText("----------------------------", true);

                    WriteText("正在下载数据......", true);
                    DownloadData(dataSvr);
                    WriteText("数据下载完成......", true);
                    WriteText("----------------------------", true);
                    WriteText("正在更新数据......", true);

                    UpdateTable(AppGlobal.HbmSessionFactory);

                    AppGlobal.DataWCF.ClientRegInfoUpdated();
                }
                else
                {
                    WriteText("当前数据是最新的!", false);
                }

            }
            catch (Exception er)
            {
                factory.Abort();
                WriteText("数据下载失败,失败信息:" + er.Message, true);
            }
            finally
            {
                WriteText("更新结束。", true);
            }

        }

        void downloadWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            btnUpdate.IsEnabled = true;

        }

        /// <summary>
        /// 检查网络是否通畅
        /// </summary>
        /// <returns></returns>
        //private bool LinkServer()
        //{
        //    WriteText("正在测试网络连接......", false);

        //    Ping pingSender = new Ping();
        //    PingReply reply = null;
        //    bool isSuccess = false;

        //    foreach (string url in urls)
        //    {
        //        Uri uri = null;
        //        try
        //        {
        //            uri = new Uri(url);
        //            reply = pingSender.Send(uri.Host);
        //            if (reply != null && (reply.Status == IPStatus.Success))
        //            {
        //                isSuccess = true;
        //                break;
        //            }
        //        }
        //        catch (Exception er)
        //        {
        //            WriteText("测试网络时发生错误，错误信息:" + er.Message, true);
        //        }
        //    }

        //    if (isSuccess)
        //        WriteText("成功。", false);
        //    else
        //        WriteText("失败！无法连接主机，请检查网络状况。", false);

        //    return isSuccess;
        //}

        private long GetMaxCheckPoint()
        {
            using (ISession sess = AppGlobal.HbmSessionFactory.OpenSession())
            {

                long r = sess.CreateSQLQuery("select max(LastTimeStamp) from System_TableUpdate where IsNeedUpdate=1 and TableType=0").List<long>()[0];
                return r;
            }

            
        }
        /// <summary>
        /// 下载数据
        /// </summary>
        /// <param name="svr"></param>
        private void DownloadData(IDataService svr)
        {
            ISession sess = null;
            try
            {
                sess = AppGlobal.HbmSessionFactory.OpenSession();
                DataUpdateManager dum = new DataUpdateManager();
                tables = dum.LoadClientDBTableInfo(TableType.Data, sess);

                foreach (var t in tables)
                {
                    WriteText("正在下载:[" + t.Description + "]......", true);
                    DBTableData ta = t.TableData;

                    string text = svr.UpdateTableData(t.Name, ta.ClientMinId, ta.ClientMaxId, ta.ClientRowCount, ta.ClientTs, "");

                    DBTableData result = Newtonsoft.Json.JsonConvert.DeserializeObject<DBTableData>(text);

                    t.SetServerTableData(result);
                    WriteText("下载完成。", false);
                }
            }
            catch (Exception er)
            {
                throw er;
            }
            finally
            {
                sess.Close();
            }
        }

        /// <summary>
        /// 更新本地数据库
        /// </summary>
        /// <param name="sf"></param>
        private void UpdateTable(ISessionFactory sf)
        {
            ISession sess = sf.OpenSession();

            IDbConnection conn = sess.Connection;

            IDbTransaction tx = conn.BeginTransaction();

            DataUpdateManager dum = new DataUpdateManager();

            try
            {
                foreach (var t in tables)
                {
                    WriteText("正在更新本地数据:[" + t.Description + "]......", true);
                    dum.UpdateTable(t, conn, tx,WriteText);
                    WriteText("更新完成。", false);
                }

                tx.Commit();
                WriteText("数据更新成功。", true);
                AppGlobal.ResultClientRegInfo.IsNewData = false;
            }
            catch (Exception er)
            {
                tx.Rollback();
                throw er;
            }
            finally
            {
                conn.Close();
                sess.Close();
            }

        }

        private void WriteText(string info,bool isNewLine)
        {
            Dispatcher.Invoke(new Action(()=>
                {
                    txtInfos.AppendText(isNewLine ? Environment.NewLine + info : info);
                    txtInfos.ScrollToEnd();
                }));
        }
    }
}
